package com.probiz.estore.core.util;

import java.io.File;
import java.util.Enumeration;

import javax.servlet.ServletContext;

import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.runas.RunAsUserToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.probiz.estore.Constants;
import com.probiz.estore.common.helper.ConfigUtil;
import com.probiz.estore.common.model.system.AppUser;

/**
 * 对整个应用环境的集中管理，包括初始化，刷新，和访问。
 * 
 */
public final class ContextUtil 
{
	private final Log logger = LogFactory.getLog(ContextUtil.class);

	private final static ContextUtil instance = new ContextUtil();

	private AppContextLoader appContextLoader;
	/**
	 * 是否web前台
	 */
    private boolean isStoreFront = false;
    /**
     * 是否手机前台
     */
    private boolean isMobileFront = false;
    /**
     * 是否web后台
     */
    private boolean isStoreAdmin = false;

    private ServletContext servletContext;

    private ApplicationContext springContext;

    private ContextUtil() {}
    
	public final static ContextUtil getInstance() {
		return instance;
	}

	public static ServletContext getServletContext() {
		return getInstance().servletContext;
	}

	public static Object getSpringBeanById(String beanId) {
		return getInstance().springContext.getBean(beanId);
	}

	public static ApplicationContext getSpringContext() {
		return getInstance().springContext;
	}

	public static boolean isStoreFront() {
		return getInstance().isStoreFront;
	}	
	
	public static boolean isMobileFront() {
		return getInstance().isMobileFront;
	}	
	public static boolean isStoreAdmin() {
		return getInstance().isStoreAdmin;
	}	
	/**
	 * 是否属于前台应用
	 * @return
	 */
	public static boolean isFront() {
		return isStoreFront() || isMobileFront();
	}	

	

	/**
	 * 整个系统的初始化工作
	 */
	public void init(ServletContext servletContext) {
		this.servletContext = servletContext;
		this.springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
		this.isStoreFront = (servletContext.getInitParameter("isStoreFront") != null);
		this.isMobileFront = (servletContext.getInitParameter("isMobileFront") != null);
		this.isStoreAdmin = (servletContext.getInitParameter("isStoreAdmin") != null);

		// register a RunAs system user
		SecurityContext sci = new SecurityContextImpl();
		AppUser systemUser = new AppUser();
		systemUser.setAppuserId(Constants.USERID_SYSTEM);
		systemUser.setUsername("system");
		sci.setAuthentication(new RunAsUserToken("SystemUser", systemUser,
				null, null, null));
		SecurityContextHolder.setContext(sci);
		
		//~~设置ConfigUtil ---------------
		ConfigUtil.getInstance().setStoreFront(isStoreFront);
		ConfigUtil.getInstance().setWebAppRootPath(servletContext.getRealPath("/"));
		
		ConfigUtil.getInstance().setMobileFront(isMobileFront);

		initAppContextLoader();
		
		autoStartScheduler();
//		//文件式的velocity不再使用
//		initVelocity();

	}
	
	protected void initAppContextLoader() {
		this.appContextLoader = (AppContextLoader) getSpringBeanById("appContextLoader");
		appContextLoader.setServletContext(servletContext);
		appContextLoader.setSpringContext(springContext);
		appContextLoader.reloadContext();
	}

	/**
	 * 系统清理工作
	 */
	public void cleanup() {
		debugContext();
		if (appContextLoader != null) {
			appContextLoader.cleanup();
		}
		this.servletContext = null;
		this.springContext = null;
	}


	/**
	 * 打印调试信息
	 */
	public void debugContext() {
		logger.info(System.getProperties());
		logger.info(System.getenv());
		if (springContext != null) {
			logger.info(springContext.toString());
		}

		if (servletContext != null) 
		{
			logger.info("!!!!!!!!!!Debuging ServletContext.getAttributeNames()!!!!!!!!!!");
			Enumeration enumeration = servletContext.getAttributeNames();
			while (enumeration.hasMoreElements()) 
			{
				String name = (String) enumeration.nextElement();
				logger.info("ServletContext Attributes - " + name + ": ["
						+ servletContext.getAttribute(name) + "].");
			}
			logger.info("!!!!!!!!!!Debuging ServletContext.getInitParameterNames()!!!!!!!!!!");
			enumeration = servletContext.getInitParameterNames();
			while (enumeration.hasMoreElements()) 
			{
				String name = (String) enumeration.nextElement();
				logger.info("ServletContext InitParameter - " + name + ": ["
						+ servletContext.getInitParameter(name) + "].");
			}
		}
	}
	
	/**
	 * 获得系统启动时间
	 * @return
	 */
	public long getStartupTime() {
		return this.springContext.getStartupDate();
	}

	/**
	 * 需要根据系统配置来创建和初始化VelocityEngine，所以这里使用定制的初始化过程
	 * @deprecated
	 * 
	 */
	private void initVelocity() {
		VelocityUtil velocityUtil = ((VelocityUtil) getSpringBeanById("velocityUtil"));
	}

	/**
	 * 判断文件是否存在
	 * @param relativeFilePath
	 * @return
	 */
	public boolean isFileExists(String relativeFilePath) {
		return new File(servletContext.getRealPath(relativeFilePath)).exists();
	}

	/**
	 * 加载菜单库
	 */
	public void reloadMenuRepository() {
		appContextLoader.reloadMenuRepository();
	}
	
	
	/**
	 * 获得spring定时器bean
	 * @return
	 */
	private Scheduler getScheduler() {
		return (Scheduler) springContext.getBean("scheduler");
	}
	/**
	 * 自动启动定时器
	 */
	private void autoStartScheduler() {
		startScheduler();
	}
	/**
	 * 开启定时器
	 */
	public void startScheduler() {
		try {
			SchedulerUtil.startupScheduler(getScheduler());
		} catch (SchedulerException e) {
			throw new RuntimeException("Start Scheduler Error!", e);
		}
	}

	/**
	 * 关闭定时器
	 */
	public void shutdownScheduler() {
		try {
			getScheduler().shutdown();
		} catch (SchedulerException e) {
			logger.error("Shutdown Scheduler Error!", e);
		}
	}

	
}
